package com.koushikdutta.ion.loader;

import com.example.ohosasynclibrary.async.future.Future;
import com.example.ohosasynclibrary.async.future.SimpleFuture;
import com.koushikdutta.ion.Ion;
import com.koushikdutta.ion.ResponseServedFrom;
import com.koushikdutta.ion.bitmap.BitmapInfo;
import ohos.agp.utils.Point;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;
import ohos.media.photokit.metadata.AVThumbnailUtils;

import java.io.File;
import java.net.URI;

/**
 * Created by koush on 11/6/13.
 */
public class VideoLoader extends SimpleLoader {
    //    @TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
    public static PixelMap createVideoThumbnail(String filePath) {
//        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//        retriever.setDataSource(filePath);
//
//        try {
//            return retriever.getFrameAtTime();
//        } finally {
//            try {
//                retriever.release();
//            } catch (Exception ignored) {
//            }
//        }
        return AVThumbnailUtils.createVideoThumbnail(new File(filePath), new Size(0, 0));
    }

//    static boolean mustUseThumbnailUtils() {
//        // http://developer.samsung.com/forum/thread/mediametadataretriever-getframeattime-to-retrieve-video-frame-fails/77/202945
//        // https://codereview.chromium.org/107523005
//        return Build.MANUFACTURER.toLowerCase().contains("samsung");
//    }

    @Override
    public Future<BitmapInfo> loadBitmap(Context context, Ion ion, final String key, final String uri, final int resizeWidth, final int resizeHeight, boolean animateGif) {
        if (!uri.startsWith("file"))
            return null;

        final MediaFile.MediaFileType type = MediaFile.getFileType(uri);
        if (type == null || !MediaFile.isVideoFileType(type.fileType))
            return null;

        final SimpleFuture<BitmapInfo> ret = new SimpleFuture<BitmapInfo>();
        Ion.getBitmapLoadExecutorService().execute(new Runnable() {
            @Override
            public void run() {
                final File file = new File(URI.create(uri));
                if (ret.isCancelled()) {
//                    Log.d("VideoLoader", "Bitmap load cancelled (no longer needed)");
                    return;
                }
                try {
                    PixelMap bmp = AVThumbnailUtils.createImageThumbnail(file, new Size(0, 0));

//                    if (mustUseThumbnailUtils() || Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD_MR1)
//                        bmp = ThumbnailUtils.createVideoThumbnail(file.getAbsolutePath(), MediaStore.Video.Thumbnails.MINI_KIND);
//                    else
//                        bmp = createVideoThumbnail(file.getAbsolutePath());
                    if (bmp == null)
                        throw new Exception("video bitmap failed to load");
                    // downsample this if its obscenely large
                    Point originalSize = new Point(bmp.getImageInfo().size.width, bmp.getImageInfo().size.height);
                    if (bmp.getImageInfo().size.width > resizeWidth * 2 && bmp.getImageInfo().size.height > resizeHeight * 2) {
                        float xratio = (float) resizeWidth / bmp.getImageInfo().size.width;
                        float yratio = (float) resizeHeight / bmp.getImageInfo().size.height;
                        float ratio = Math.min(xratio, yratio);
                        if (ratio != 0)
//                            bmp = Bitmap.createScaledBitmap(bmp, (int) (bmp.getWidth() * ratio), (int) (bmp.getHeight() * ratio), true);
                            bmp = PixelMap.create(bmp, new Rect(0, 0, (int) (bmp.getImageInfo().size.width * ratio), (int) (bmp.getImageInfo().size.height * ratio)), new PixelMap.InitializationOptions());
                    }
                    BitmapInfo info = new BitmapInfo(key, type.mimeType, bmp, originalSize);
                    info.servedFrom = ResponseServedFrom.LOADED_FROM_CACHE;
                    ret.setComplete(info);
                } catch (OutOfMemoryError e) {
                    ret.setComplete(new Exception(e));
                } catch (Exception e) {
                    ret.setComplete(e);
                }
            }
        });
        return ret;
    }
}
